<!-- 账号密码登录页 -->
<template>
	<view class="app-container" :style="backgroundStyle">
		<view class="login-container">
			<text class="login-title">自助拍照系统</text>
			
			<view class="form">
				<view class="input-group relative mb-6">
					<text class="input-label">账号</text>
					<view class="input-container relative">
						<view class="input-icon">
							<uni-icons type="person" size="18" color="#5f6368"></uni-icons>
						</view>
						<input type="text" v-model="username" class="input-field input-with-icon" placeholder="请输入手机号/用户名/邮箱" />
					</view>
				</view>
				
				<view class="input-group relative mb-8">
					<text class="input-label">密码</text>
					<view class="input-container relative">
						<view class="input-icon">
							<uni-icons type="locked" size="18" color="#5f6368"></uni-icons>
						</view>
						<input :type="showPassword ? 'text' : 'password'" v-model="password" class="input-field input-with-icon" placeholder="请输入密码" />
						<view class="eye-icon" @click="togglePasswordVisibility">
							<uni-icons :type="showPassword ? 'eye-slash' : 'eye'" size="18" color="#5f6368"></uni-icons>
						</view>
					</view>
				</view>
				
				<view class="input-group relative mb-8" v-if="needCaptcha">
					<text class="input-label">验证码</text>
					<view class="input-container relative">
						<view class="input-icon">
							<uni-icons type="locked" size="18" color="#5f6368"></uni-icons>
		</view>
						<input type="text" v-model="captcha" class="input-field input-with-icon" placeholder="请输入验证码" />
						<view class="captcha-image">
		<uni-captcha v-if="needCaptcha" focus ref="captcha" scene="login-by-pwd" v-model="captcha" />
						</view>
					</view>
				</view>
				
				<!-- 隐藏协议组件，但仍默认同意 -->
				<view style="display: none;">
		<uni-id-pages-agreements scope="login" ref="agreements"></uni-id-pages-agreements>
				</view>
				
				<view class="privacy-tip mb-6">
					<text class="privacy-text">登录即表示您同意</text>
					<text class="privacy-link">《用户服务协议》</text>
					<text class="privacy-text">和</text>
					<text class="privacy-link">《隐私政策》</text>
				</view>
				
				<button type="button" class="btn btn-primary w-full" @click="pwdLogin" :disabled="isLoading">
					<text v-if="isLoading">登录中...</text>
					<text v-else>登录</text>
				</button>
			</view>
		</view>
		
		<view class="contact-btn" @click="showContactModal">
			<uni-icons type="phone-filled" size="16" color="#5f6368" class="mr-2"></uni-icons>
			<text>联系方式</text>
		</view>
		
		<!-- 联系方式模态框修改为使用uni-popup方式 -->
		<uni-popup ref="contactPopup" type="center" :mask-click="true">
			<view class="modal-container">
				<view class="modal-header">
					<view class="modal-title">联系方式</view>
					<view class="modal-close" @click="closeContactModal">
						<uni-icons type="closeempty" size="20" color="#5f6368"></uni-icons>
					</view>
				</view>
				<view class="modal-body">
					<view class="flex justify-center mb-6" v-if="contactQrcode">
						<image :src="contactQrcode" class="qrcode-image" mode="aspectFit"></image>
					</view>
					<view v-if="contactInfo" class="contact-info">
						<rich-text :nodes="formattedContactInfo"></rich-text>
					</view>
				</view>
			</view>
		</uni-popup>
	</view>
</template>

<script>
	import mixin from '@/uni_modules/uni-id-pages/common/login-page.mixin.js';
	// 直接导入uni-popup组件
	import uniPopup from '@/uni_modules/uni-popup/components/uni-popup/uni-popup.vue';
	
	const uniIdCo = uniCloud.importObject("uni-id-co", {
		errorOptions: {
			type: 'toast'
		}
	})
	
	// 全局背景图缓存配置
	const BG_CACHE = {
		key: 'app_background_image',
		expireKey: 'app_background_expire',
		expireHours: 24,
		fallbackColor: '#f0f2f5',
		defaultImage: '/static/login-bg.jpg'
	};
	
	// 全局背景图获取方法，可以在其他页面调用
	export const getAppBackground = async () => {
		// 先尝试从缓存获取
		try {
			const cachedImage = uni.getStorageSync(BG_CACHE.key);
			const cachedExpire = uni.getStorageSync(BG_CACHE.expireKey);
			const now = new Date().getTime();
			
			if (cachedImage && cachedExpire && now < cachedExpire) {
				console.log('[全局] 从缓存获取背景图:', cachedImage);
				return cachedImage;
			}
		} catch (error) {
			console.error('[全局] 从缓存获取背景图失败:', error);
		}
		
		// 缓存不存在或已过期，尝试加载默认图片
		try {
			console.log('[全局] 使用默认背景图:', BG_CACHE.defaultImage);
			return BG_CACHE.defaultImage;
		} catch (error) {
			console.error('[全局] 加载默认背景图失败:', error);
			return BG_CACHE.fallbackColor;
		}
	};
	
	export default {
		mixins: [mixin],
		components: {
			// 使用静态导入的方式注册组件
			uniPopup
		},
		data() {
			console.log('登录页初始化');
			return {
				"password": "",
				"username": "",
				"captcha": "",
				"needCaptcha": false,
				"focusUsername": false,
				"focusPassword": false,
				"logo": "/static/logo.png",
				"showPassword": false,
				"isLoading": false,
				"contactQrcode": '',
				"contactInfo": '',
				"backgroundImage": BG_CACHE.defaultImage,
				"backgroundLoading": false,
				"backgroundError": null,
				"fallbackColor": BG_CACHE.fallbackColor, // 添加纯色背景作为最终备选
				"cacheKey": BG_CACHE.key, // 背景图缓存的key
				"cacheExpireKey": BG_CACHE.expireKey, // 背景图缓存过期时间的key
				"cacheExpireHours": BG_CACHE.expireHours, // 缓存过期时间（小时）
				"agree": true // 默认同意协议
			}
		},
		computed: {
			formattedContactInfo() {
				if (!this.contactInfo) return '';
				// 将换行符转换为HTML换行
				return this.contactInfo.replace(/\n/g, '<br>');
			},
			// 计算背景样式，确保正确应用
			backgroundStyle() {
				console.log('应用背景图片样式:', this.backgroundImage);
				
				// 检查是否使用纯色背景（作为最终备选）
				if (this.backgroundImage.startsWith('#')) {
					return {
						backgroundColor: this.backgroundImage,
					};
				}
				
				// 为避免CSS加载问题，将所有必要的背景样式都放在内联样式中
				return {
					backgroundImage: `url('${this.backgroundImage}')`,
					backgroundSize: 'cover',
					backgroundPosition: 'center',
					backgroundRepeat: 'no-repeat'
				};
			}
		},
		onLoad() {
			console.log('登录页面onLoad生命周期触发');
			// 尝试先从缓存加载背景图
			this.loadBackgroundFromCache();
		},
		onShow() {
			console.log('登录页面onShow生命周期触发');
			// #ifdef H5
			document.onkeydown = event => {
				var e = event || window.event;
				if (e && e.keyCode == 13) { //回车键的键值为13
					this.pwdLogin()
				}
			};
			// #endif
			
			// 强制延迟加载背景图，避免可能的生命周期冲突
			setTimeout(() => {
				this.getContactInfo();
			}, 100);
		},
		onReady() {
			console.log('登录页面onReady生命周期触发');
		},
		methods: {
			// 从缓存加载背景图
			loadBackgroundFromCache() {
				try {
					console.log('尝试从缓存加载背景图');
					const cachedImage = uni.getStorageSync(this.cacheKey);
					const cachedExpire = uni.getStorageSync(this.cacheExpireKey);
					const now = new Date().getTime();
					
					// 检查是否有缓存且缓存未过期
					if (cachedImage && cachedExpire && now < cachedExpire) {
						console.log('从缓存加载背景图成功:', cachedImage);
						this.backgroundImage = cachedImage;
						
						// 测试缓存的图片是否可访问
						this.testImageAccess(cachedImage);
						
						// 预加载一下，确保图片已加载
						const img = new Image();
						img.src = cachedImage;
						
						return true;
					} else {
						console.log('缓存的背景图不存在或已过期');
						return false;
					}
				} catch (error) {
					console.error('从缓存加载背景图失败:', error);
					return false;
				}
			},
			
			// 保存背景图到缓存
			saveBackgroundToCache(imageUrl) {
				try {
					if (!imageUrl || imageUrl.startsWith('#')) {
						console.log('不缓存纯色背景');
						return;
					}
					
					console.log('保存背景图到缓存:', imageUrl);
					// 设置缓存过期时间
					const expireTime = new Date().getTime() + (this.cacheExpireHours * 60 * 60 * 1000);
					
					// 保存背景图URL和过期时间
					uni.setStorageSync(this.cacheKey, imageUrl);
					uni.setStorageSync(this.cacheExpireKey, expireTime);
					
					console.log('背景图缓存成功，过期时间:', new Date(expireTime).toLocaleString());
				} catch (error) {
					console.error('保存背景图到缓存失败:', error);
				}
			},
			// 处理可能的云存储路径
			async processCloudPath(url) {
				console.log('处理图片路径:', url);
				
				// 检查是否是云存储路径
				if (url && url.startsWith('cloud://')) {
					try {
						console.log('检测到云存储路径，尝试转换:', url);
						const result = await uniCloud.getTempFileURL({
							fileList: [url]
						});
						console.log('云存储路径转换结果:', result);
						
						if (result.fileList && result.fileList[0] && result.fileList[0].tempFileURL) {
							console.log('云存储路径转换成功:', result.fileList[0].tempFileURL);
							return result.fileList[0].tempFileURL;
						} else {
							console.error('云存储路径转换失败，使用默认图片');
							return '/static/login-bg.jpg';
						}
					} catch (error) {
						console.error('云存储路径转换出错:', error);
						return '/static/login-bg.jpg';
					}
				}
				
				// 非云存储路径，直接返回
				return url;
			},
			
			// 获取联系方式和背景图信息
			async getContactInfo() {
				console.log('开始获取设置信息');
				this.backgroundLoading = true;
				this.backgroundError = null;
				
				// 如果已经从缓存加载了背景图，则跳过云端加载
				const hasCachedBg = this.loadBackgroundFromCache();
				
				try {
					const db = uniCloud.database();
					const settingsCollection = db.collection('a-settings');
					console.log('已初始化数据库连接');
					
					// 获取联系电话
					console.log('开始获取联系电话');
					const contactRes = await settingsCollection.where({
						key: 'about_contact'
					}).get();
					
					console.log('联系电话查询结果详情:', JSON.stringify(contactRes));
					// 修复：同时检查 result.data 和 data 路径
					if (contactRes.result && contactRes.result.data && contactRes.result.data.length > 0) {
						this.contactInfo = contactRes.result.data[0].value;
						console.log('设置联系电话成功(result.data路径):', this.contactInfo);
					} else if (contactRes.data && contactRes.data.length > 0) {
						this.contactInfo = contactRes.data[0].value;
						console.log('设置联系电话成功(data路径):', this.contactInfo);
					} else {
						console.log('未找到联系电话信息');
					}
					
					// 获取联系二维码
					console.log('开始获取联系二维码');
					const qrcodeRes = await settingsCollection.where({
						key: 'about_qrcode'
					}).get();
					
					console.log('联系二维码查询结果详情:', JSON.stringify(qrcodeRes));
					// 修复：同时检查 result.data 和 data 路径
					if (qrcodeRes.result && qrcodeRes.result.data && qrcodeRes.result.data.length > 0) {
						const qrcodeUrl = qrcodeRes.result.data[0].value;
						this.contactQrcode = await this.processCloudPath(qrcodeUrl);
						console.log('设置联系二维码成功(result.data路径):', this.contactQrcode);
					} else if (qrcodeRes.data && qrcodeRes.data.length > 0) {
						const qrcodeUrl = qrcodeRes.data[0].value;
						this.contactQrcode = await this.processCloudPath(qrcodeUrl);
						console.log('设置联系二维码成功(data路径):', this.contactQrcode);
					} else {
						console.log('未找到联系二维码，使用默认值');
						this.contactQrcode = '/static/contact-qrcode.png';
					}
					
					// 如果已经从缓存加载了背景图，则跳过云端加载
					if (hasCachedBg) {
						console.log('已从缓存获取背景图，跳过云端获取');
						return;
					}
					
					// 获取背景图片
					console.log('开始获取背景图片');
					const bgRes = await settingsCollection.where({
						key: 'home_background'
					}).get();
					
					console.log('背景图片查询结果完整数据:', JSON.stringify(bgRes));
					
					// 关键修复：正确解析返回的数据结构
					if (bgRes && bgRes.result && bgRes.result.data && bgRes.result.data.length > 0) {
						console.log('找到背景图片配置 - 使用result.data路径');
						const data = bgRes.result.data[0];
						await this.processBackgroundData(data);
					} else if (bgRes && bgRes.data && bgRes.data.length > 0) {
						console.log('找到背景图片配置 - 使用data路径');
						const data = bgRes.data[0];
						await this.processBackgroundData(data);
					} else {
						console.error('未找到背景图片数据，检查返回结构:', bgRes);
						await this.setFallbackBackground();
					}
				} catch (e) {
					console.error('获取设置信息失败, 详细错误:', e);
					this.backgroundError = e.message || '未知错误';
					
					// 如果未从缓存加载成功，则设置备选背景
					if (!hasCachedBg) {
						await this.setFallbackBackground();
					}
				} finally {
					this.backgroundLoading = false;
					console.log('设置信息获取流程完成，最终背景图片URL:', this.backgroundImage);
					
					// 延迟再次测试背景图
					setTimeout(() => {
						// 测试背景样式
						console.log('当前应用的背景样式:', this.backgroundStyle);
					}, 500);
				}
			},
			
			// 处理背景数据
			async processBackgroundData(data) {
				if (!data || !data.value) {
					console.error('背景数据无效:', data);
					await this.setFallbackBackground();
					return;
				}
				
				const backgrounds = data.value;
				console.log('背景图片数组:', backgrounds);
				
				if (!Array.isArray(backgrounds) || backgrounds.length === 0) {
					console.error('背景数组无效或为空');
					await this.setFallbackBackground();
					return;
				}
				
				// 查找默认背景图片
				const defaultBg = backgrounds.find(bg => bg.is_default === true);
				const selectedBg = defaultBg || backgrounds[0];
				
				console.log('选择的背景图片:', selectedBg);
				
				if (!selectedBg || !selectedBg.url) {
					console.error('背景图片URL无效');
					await this.setFallbackBackground();
					return;
				}
				
				// 提取URL
				const imageUrl = selectedBg.url;
				console.log('背景图片原始URL:', imageUrl);
				
				// 处理URL
				try {
					let processedUrl;
					
					if (imageUrl.startsWith('cloud://')) {
						console.log('云存储链接，尝试转换');
						processedUrl = await this.processCloudPath(imageUrl);
					} else if (imageUrl.startsWith('http')) {
						console.log('HTTP直接链接，直接使用');
						processedUrl = imageUrl;
					} else {
						console.log('其他类型链接，使用原始值');
						processedUrl = imageUrl;
					}
					
					console.log('处理后URL:', processedUrl);
					
					// 测试图片可访问性
					const isAccessible = await this.testImageAccessAsync(processedUrl);
					
					if (isAccessible) {
						console.log('图片可访问，设置为背景');
						this.backgroundImage = processedUrl;
						this.$forceUpdate();
						
						// 将可访问的图片URL保存到缓存
						this.saveBackgroundToCache(processedUrl);
					} else {
						console.error('处理后的图片不可访问，使用备选');
						await this.setFallbackBackground();
					}
				} catch (urlError) {
					console.error('处理背景图URL出错:', urlError);
					await this.setFallbackBackground();
				}
			},
			
			// 设置备选背景
			async setFallbackBackground() {
				console.log('尝试设置备选背景图');
				
				// 先尝试本地静态背景图
				const staticPath = '/static/login-bg.jpg';
				const isStaticAccessible = await this.testImageAccessAsync(staticPath);
				
				if (isStaticAccessible) {
					console.log('本地静态背景图可访问，使用它');
					this.backgroundImage = staticPath;
				} else {
					console.log('本地静态背景图不可访问，使用纯色背景');
					// 最终备选：使用纯色背景
					this.backgroundImage = this.fallbackColor;
				}
				
				this.$forceUpdate();
			},
			
			// 异步测试图片是否可以访问
			testImageAccessAsync(url) {
				if (!url || url.startsWith('#')) {
					return Promise.resolve(false);
				}
				
				return new Promise(resolve => {
					console.log('异步测试图片是否可访问:', url);
					const img = new Image();
					
					img.onload = () => {
						console.log('✅ 图片加载成功:', url);
						resolve(true);
					};
					
					img.onerror = () => {
						console.error('❌ 图片加载失败:', url);
						resolve(false);
					};
					
					// 添加超时处理
					setTimeout(() => {
						if (!img.complete) {
							console.error('⏱ 图片加载超时:', url);
							resolve(false);
						}
					}, 5000);
					
					img.src = url;
				});
			},
			
			// 测试图片是否可以访问
			testImageAccess(url) {
				if (!url || url.startsWith('data:') || url.startsWith('blob:') || url.startsWith('#')) {
					console.log('图片URL是特殊格式，无需测试');
					return;
				}
				
				console.log('测试图片是否可访问:', url);
				// 创建一个临时的Image对象
				const img = new Image();
				
				img.onload = () => {
					console.log('✅ 图片加载成功:', url);
				};
				
				img.onerror = () => {
					console.error('❌ 图片加载失败:', url);
				};
				
				// 设置图片源，开始加载
				img.src = url;
			},
			
			togglePasswordVisibility() {
				this.showPassword = !this.showPassword;
			},
			
			// 显示联系方式模态框
			showContactModal() {
				// 检查组件引用是否存在
				if (this.$refs && this.$refs.contactPopup) {
					console.log('打开联系方式模态框');
					this.$refs.contactPopup.open();
				} else {
					console.error('联系方式模态框引用不存在');
					// 异步等待组件加载完成
					setTimeout(() => {
						if (this.$refs && this.$refs.contactPopup) {
							console.log('延迟打开联系方式模态框');
							this.$refs.contactPopup.open();
						} else {
							uni.showToast({
								title: '联系方式加载失败',
								icon: 'none'
							});
						}
					}, 500);
				}
			},
			
			// 关闭联系方式模态框
			closeContactModal() {
				if (this.$refs && this.$refs.contactPopup) {
					this.$refs.contactPopup.close();
				}
			},
			
			/**
			 * 密码登录
			 */
			pwdLogin() {
				if (!this.password.length) {
					this.focusPassword = true
					return uni.showToast({
						title: '请输入密码',
						icon: 'none',
						duration: 3000
					});
				}
				if (!this.username.length) {
					this.focusUsername = true
					return uni.showToast({
						title: '请输入手机号/用户名/邮箱',
						icon: 'none',
						duration: 3000
					});
				}
				if (this.needCaptcha && this.captcha.length != 4) {
					this.$refs.captcha.getImageCaptcha()
					return uni.showToast({
						title: '请输入验证码',
						icon: 'none',
						duration: 3000
					});
				}

				// 设置加载状态
				this.isLoading = true;

				let data = {
					"password": this.password,
					"captcha": this.captcha
				}

				if (/^1\d{10}$/.test(this.username)) {
					data.mobile = this.username
				} else if (/@/.test(this.username)) {
					data.email = this.username
				} else {
					data.username = this.username
				}

				uniIdCo.login(data).then(e => {
					// 新的登录成功处理：存储token信息
					uni.setStorageSync('uni_id_token', e.newToken.token);
					
					// 打印登录成功信息
					console.log('登录成功，详细信息：', {
						uid: e.uid,
						token: e.newToken.token,
						tokenExpired: e.newToken.tokenExpired,
						passwordConfirmed: e.passwordConfirmed
					});
					
					// 显示登录成功提示
					uni.showToast({
						title: '登录成功',
						icon: 'success',
						duration: 2000
					});
					
					// 完全避免使用uni.redirectTo等导航API，直接使用window.location硬重定向
					setTimeout(() => {
						// 处理H5环境
						if (typeof window !== 'undefined') {
							// 避免使用Vue路由或uni-app导航API
							if (window.location.href.indexOf('#') > -1) {
								// Hash模式
								window.location.href = window.location.href.split('#')[0] + '#/pages/start/index';
							} else {
								// History模式
								window.location.replace('/pages/start/index');
							}
						} else {
							// 小程序或App环境，尝试最基础的跳转方式
							try {
								// 完全重置应用状态
								plus && plus.navigator.closeSplashscreen();
								plus && plus.runtime.restart();
							} catch (e) {
								console.error('环境重启失败', e);
							}
						}
					}, 1200);
					
					this.isLoading = false;
				}).catch(e => {
					if (e.errCode == 'uni-id-captcha-required') {
						this.needCaptcha = true
					} else if (this.needCaptcha) {
						//登录失败，自动重新获取验证码
						this.$refs.captcha.getImageCaptcha()
					}
					this.isLoading = false;
				})
			}
		}
	}
</script>

<style lang="scss" scoped>
/* 页面样式 */
.app-container {
	position: relative;
	width: 100%;
	height: 100vh;
	display: flex;
	align-items: center;
	justify-content: center;
	background-size: cover;
	background-position: center;
}

.login-container {
	background-color: rgba(255, 255, 255, 0.9);
	border-radius: 16px;
	box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
	width: 90%;
	max-width: 600px;
	padding: 40px;
	position: relative;
	z-index: 2;
}

.login-title {
	font-size: 28px;
	font-weight: 700;
	margin-bottom: 30px;
	text-align: center;
	color: #1a73e8;
}

.form {
	width: 100%;
	display: flex;
	flex-direction: column;
	align-items: center;
}

.input-group {
	margin-bottom: 20px;
	width: 100%;
}

.input-container {
	width: 100%;
	position: relative;
}

.input-label {
	display: block;
	font-size: 16px;
	font-weight: 500;
	color: #202124;
	margin-bottom: 8px;
}

.input-field {
	width: 100%;
	height: 48px;
	border: 1px solid #dadce0;
	border-radius: 8px;
	padding: 0 16px;
	font-size: 16px;
	color: #202124;
	background-color: white;
	box-sizing: border-box;
}

.input-with-icon {
	padding-left: 48px;
	padding-right: 16px;
	width: 100%;
	box-sizing: border-box;
}

.input-icon {
	position: absolute;
	top: 50%;
	transform: translateY(-50%);
	left: 16px;
	color: #5f6368;
	font-size: 18px;
}

.eye-icon {
	position: absolute;
	top: 50%;
	transform: translateY(-50%);
	right: 16px;
	color: #5f6368;
	font-size: 18px;
}

.btn {
	height: 48px;
	border-radius: 8px;
	font-size: 16px;
	font-weight: 500;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 100%;
}

.btn-primary {
	background-color: #1a73e8;
	color: white;
}

.btn-primary[disabled] {
	background-color: #a1c0ea;
	color: #f1f3f4;
}

.contact-btn {
	position: fixed;
	bottom: 20px;
	right: 20px;
	background-color: rgba(255, 255, 255, 0.8);
	border-radius: 8px;
	padding: 10px 20px;
	font-weight: 500;
	color: #5f6368;
	box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
	display: flex;
	align-items: center;
	transition: all 0.2s ease;
	z-index: 10;
}

.contact-btn:hover {
	background-color: rgba(255, 255, 255, 1);
	box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}

/* 模态框样式 */
.modal-container {
	background-color: white;
	border-radius: 12px;
	box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
	width: 90%;
	max-width: 500px;
	overflow: hidden;
}

.modal-header {
		display: flex;
		justify-content: space-between;
	align-items: center;
	padding: 16px 24px;
	border-bottom: 1px solid #e0e0e0;
}

.modal-title {
	font-size: 18px;
	font-weight: 600;
	color: #202124;
}

.modal-close {
	background: none;
	border: none;
	font-size: 20px;
	color: #5f6368;
	padding: 4px;
	border-radius: 50%;
	display: flex;
	align-items: center;
	justify-content: center;
	transition: background-color 0.2s;
}

.modal-close:hover {
	background-color: #f1f3f4;
}

.modal-body {
	padding: 24px;
}

.qrcode-image {
	width: 200px;
	height: 200px;
}

.contact-info {
	font-size: 16px;
	line-height: 1.6;
	color: #3c4043;
}

.privacy-tip {
	font-size: 13px;
	text-align: center;
	color: #5f6368;
	width: 100%;
}

.privacy-text {
	color: #5f6368;
}

.privacy-link {
	color: #1a73e8;
}

.captcha-image {
	position: absolute;
	top: 50%;
	transform: translateY(-50%);
	right: 16px;
	height: 36px;
	width: 100px;
	display: flex;
	align-items: center;
	justify-content: center;
	background-color: #f5f5f5;
	border-radius: 4px;
	overflow: hidden;
}

/* 辅助类 */
.flex {
	display: flex;
}

.items-center {
	align-items: center;
}

.justify-center {
	justify-content: center;
}

.mb-4 {
	margin-bottom: 16px;
}

.mb-6 {
	margin-bottom: 24px;
}

.mb-8 {
	margin-bottom: 32px;
}

.mr-2 {
	margin-right: 8px;
}

.w-full {
	width: 100%;
}

.text-gray-600 {
	color: #5f6368;
}

.relative {
	position: relative;
	}
</style>
